package com.interview.javabase.algorithm.hand.读写锁;

import org.assertj.core.util.Strings;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 手写读写锁
 *
 * @author zhangshguang
 * @date 2020/07/27
 */
public class HandReadWriteLock {

    /**
     * 等待写的数量
     */
    private volatile int waitingWriteLock = 0;

    /**
     * 正在读的
     */
    private volatile int readLock = 0;

    public volatile int index = 0;

    public synchronized void readLock() throws InterruptedException {

        String.join("/n",new ArrayList<>());
        while (waitingWriteLock > 0) {
            this.wait();

        }
        readLock++;
    }

    public synchronized void unReadLock() throws InterruptedException {
        readLock--;
        notifyAll();
    }

    public synchronized void writeLock() throws InterruptedException {
        while (waitingWriteLock > 0) {
            this.wait();
        }

        waitingWriteLock++;
    }

    public synchronized void unWriteLock() throws InterruptedException {
        waitingWriteLock--;
        notifyAll();
    }

    public static void main(String[] args) throws InterruptedException {
        HandReadWriteLock readWriteLockDemo = new HandReadWriteLock();

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {

                    readWriteLockDemo.readLock();
                    System.out.println(readWriteLockDemo.index);
                    Thread.sleep(5000);
                    readWriteLockDemo.unReadLock();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }


        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                try {
                    readWriteLockDemo.writeLock();
                    Thread.sleep(100);

                readWriteLockDemo.index++;
                System.out.println(readWriteLockDemo.index);
                    readWriteLockDemo.unWriteLock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
